﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SHKF.B2C.Erp.BLL; 
using SHKF.B2C.Erp.BLL.SugarIOC;
using SHKF.B2C.ErpServices.Model;
using SHKF.B2C.Model.Entity.Center;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace SHKF.B2C.ErpServices
{
    public static class HostedExtensions
    {
        public static IHostBuilder UseRun(this IHostBuilder hostBuilder, string hostJson = "")
        {
            //加载配置文件
            hostBuilder.ConfigureHostConfiguration(configBuilder =>
            { 
                configBuilder.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); 
                configBuilder.AddJsonFile("json/dbErpList.json", true);
                configBuilder.AddJsonFile("json/dbList.json", true);

                if (!string.IsNullOrEmpty(hostJson))
                {
                    foreach (string jsonPath in hostJson.Split(','))
                    {
                        configBuilder.AddJsonFile(jsonPath, true);
                    }
                }
            });

            //日志
            hostBuilder.ConfigureLogging((context, loggingBuilder) =>
             {
                 loggingBuilder.ClearProviders();
                 loggingBuilder.AddLog4Net(new Log4NetProviderOptions()
                 {
                     Log4NetConfigFileName = "Configs\\log4net.config",
                     Watch = true
                 });
             });

            //数据库
            hostBuilder.ConfigureServices((context, services) => {

                services.AddAllBLL();
                services.AddB2CDB(context);
                services.AddErpDB(context);

            } );

            hostBuilder.UseWindowsService();//window部署

            return hostBuilder;
        }

        private static IServiceCollection AddB2CDB(this IServiceCollection services, HostBuilderContext context)
        {

            services.Configure<List<DbEnum>>(context.Configuration.GetSection("DBList"));
            IOptions<List<DbEnum>> dbList = services.BuildServiceProvider().GetService<IOptions<List<DbEnum>>>();

            WriteRunLog("//------------------------------添加DBList:");
            if (dbList != null)
            {
                string ip = context.Configuration.GetSection("ip").Value;

                if (!string.IsNullOrEmpty(ip))
                {
                    List<ConnectionConfig> iocList = new List<ConnectionConfig>();

                    foreach (DbEnum dbEnum in dbList.Value)
                    {
                        string dbConn = $"{ip}" + dbEnum.dbConn;

                        ConnectionConfig connectionConfig = new ConnectionConfig();
                        connectionConfig.ConfigId = dbEnum.dbName;
                        connectionConfig.ConnectionString = dbConn;
                        connectionConfig.DbType = DbType.SqlServer;
                        connectionConfig.IsAutoCloseConnection = true;
                        iocList.Add(connectionConfig);

                        WriteRunLog($"dbName:{dbEnum.dbName} dbConn:{dbEnum.dbConn}");
                    }

                    //B2C的数据库单独创建
                    services.AddTransient<SqlSugarClient>((server) =>
                    {
                        return new SqlSugarClient(iocList);
                    });

                }
            }

            return services;
        }



        /// <summary>
        /// 添加数据库实例
        /// </summary>
        /// <param name="services"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private static IServiceCollection AddErpDB(this IServiceCollection services, HostBuilderContext context)
        {
            WriteRunLog("//------------------------------添加DBList:");

            //先从数据库里取，如果数据库里没有再从配置文件里取 
            bool bOK = AddErpDBOfDb(services);
            if(!bOK)
            {
                AddErpDBOfConfig(services, context);
            } 

            return services;
        }
 
        private static void AddErpDBOfConfig(IServiceCollection services, HostBuilderContext context)
        {
            IConfigurationSection configurationSection = context.Configuration.GetSection("ServerList");
            services.Configure<List<DBServer>>(configurationSection);
            IOptions<List<DBServer>> dbList = services.BuildServiceProvider().GetService<IOptions<List<DBServer>>>();

            if (dbList != null)
            {
                //数据库实例列表
                foreach (DBServer dBServer in dbList.Value)
                {
                    List<ConnectionConfig> iocList = new List<ConnectionConfig>();

                    //数据库列表
                    foreach (DBConfig dbEnum in dBServer.DBList)
                    {
                        string ip = dBServer.IP; //服务实例
                        string dbConn = $"{ip}" + dbEnum.dbConn;

                        ConnectionConfig connectionConfig = new ConnectionConfig();
                        connectionConfig.ConfigId = dbEnum.dbName;
                        connectionConfig.ConnectionString = dbConn;
                        connectionConfig.DbType = DbType.SqlServer;
                        connectionConfig.IsAutoCloseConnection = true;
                        iocList.Add(connectionConfig);

                        WriteRunLog($"dbName:{dbEnum.dbName} dbConn:{dbEnum.dbConn}");
                    }

                    SugarServiceExtensions.AddSqlSugar(dBServer.ServerName, iocList);
                }
            }

        }
        private static bool AddErpDBOfDb(IServiceCollection services)
        {
            try
            {
                SqlSugarClient db = services.BuildServiceProvider().GetService<SqlSugarClient>();
                db.ChangeDatabase("PtE_Center");

                WriteRunLog("//------------------------------添加DBList--从数据中获取:");
                List<ErpServerEntity> serverList = db.Queryable<ErpServerEntity>().ToList();
                if (serverList.Count > 0)
                {
                    foreach (ErpServerEntity dBServer in serverList)
                    {
                        List<ConnectionConfig> iocList = new List<ConnectionConfig>();

                        //数据库列表
                        List<ErpDataBaseEntity> DBList = db.Queryable<ErpDataBaseEntity>()
                            .Where(ww => ww.FKSN == dBServer.SN)
                            .ToList();
                        foreach (ErpDataBaseEntity dbEnum in DBList)
                        {
                            string ip = dBServer.IP; //服务实例
                            string dbConn = $"{ip}" + dbEnum.dbConn;

                            ConnectionConfig connectionConfig = new ConnectionConfig();
                            connectionConfig.ConfigId = dbEnum.dbName;
                            connectionConfig.ConnectionString = dbConn;
                            connectionConfig.DbType = DbType.SqlServer;
                            connectionConfig.IsAutoCloseConnection = true;
                            iocList.Add(connectionConfig);

                            WriteRunLog($"dbName:{dbEnum.dbName} dbConn:{dbEnum.dbConn}");
                        }

                        SugarServiceExtensions.AddSqlSugar(dBServer.ServerName, iocList);
                    }
                    return true;
                }
                return false; 
            }
            catch (Exception ex)
            {
                WriteRunLog("--从数据中获取:" + ex.Message);
                return false;
            } 
        }

        public static IServiceCollection AddAllBLL(this IServiceCollection services)
        {
            string root = AppDomain.CurrentDomain.BaseDirectory;
            string[] files = Directory.GetFiles(root);

            WriteRunLog("//------------------------------添加Bll:");
            foreach (string fileName in files)
            {
                FileInfo fileInfo = new FileInfo(fileName);

                if (fileInfo.Name.EndsWith("BLL.dll"))
                {
                    string assemblyString = fileInfo.Name.Replace(fileInfo.Extension, "");
                    Assembly assemblys = Assembly.Load(assemblyString);
                    foreach (Type type in assemblys.GetTypes())
                    {
                        bool bBLLCls = type.Name.Contains("BLL");
                        if (type.IsPublic && bBLLCls)
                        {
                            WriteRunLog("AddTransient:" + type.FullName);
                            services.AddTransient(type);
                        }
                    }
                }
            }
            return services;
        }

        private static void WriteRunLog(string context)
        {
            string root = AppDomain.CurrentDomain.BaseDirectory;
            string runPath = root + "run";

            if (!System.IO.Directory.Exists(runPath))
            {
                Directory.CreateDirectory(runPath);
            }
            string path = $"{runPath}\\{DateTime.Now.ToString("yyyy-MM-dd")}.log";
            System.IO.File.AppendAllText(path, $"{DateTime.Now} {context}\r\n");

        }

    }


   
}
